/*
 * kanji.h
 *
 * Copyright (C) 2011, 2012 - Massimiliano Maniscalco
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _KANJI_H_
#define _KANJI_H_

#include "voce.h"

using namespace std;

class Kanji: public Voce
{
	
public:
	Kanji( const Glib::ustring &str = "" ) :
		_kanji ( str ), _significato ( "" ), _radicale ( "" ), _tratti ( 0 ), _trattiRadicale ( 0 )
	{
		_onyomi = new list<Glib::ustring>;
		_kunyomi = new list<Glib::ustring>;
	}
	inline Kanji ( const Kanji &kan );
	inline ~Kanji();
	inline bool operator<( const Kanji &kan ) const;
	inline bool operator==( const Kanji &kan ) const;
	inline void set_kanji ( const Glib::ustring &str ) { _kanji.assign ( str ); }
	inline void set_kanji ( const char *cstr );
	inline Glib::ustring get_kanji ( void ) const { return _kanji; }
	static bool is_kanji ( const Glib::ustring &str );
	inline void set_onyomi ( const list<Glib::ustring> &setStr );
	inline void set_onyomi ( const Glib::ustring &str );
	inline Glib::ustring get_onyomi ( void ) const;
	inline bool contiene_onyomi ( const Glib::ustring &str ) const { return contiene_stringa ( *_onyomi, str ); }
	inline unsigned char count_onyomi ( void ) const { return _onyomi->size(); }
	inline void set_kunyomi ( const list<Glib::ustring> &setStr );
	inline void set_kunyomi ( const Glib::ustring &str );
	inline Glib::ustring get_kunyomi ( void ) const;
	inline bool contiene_kunyomi ( const Glib::ustring &str ) const { return contiene_stringa ( *_kunyomi, str ); }
	inline unsigned char count_kunyomi ( void ) const { return _kunyomi->size(); }
	inline void set_significato ( const Glib::ustring &str ) { _significato.assign ( str ); }
	inline void set_significato ( const char *cstr );
	inline Glib::ustring get_significato ( void ) const { return _significato; }
	inline void set_radicale ( const Glib::ustring &str ) { _radicale.assign ( str ); }
	inline void set_radicale ( const char *cstr );
	inline Glib::ustring get_radicale ( void ) const { return _radicale; }
	inline void set_tratti ( unsigned char val ) { _tratti = val; }
	inline void set_tratti ( const char *cstr ) { _tratti = atoi ( cstr ); }
	inline unsigned char get_tratti ( void ) const { return _tratti; }
	inline void set_tratti_radicale ( unsigned char val ) { _trattiRadicale = val; }
	inline void set_tratti_radicale ( const char *cstr ) { _trattiRadicale = atoi ( cstr ); }
	inline unsigned char get_tratti_radicale ( void ) const { return _trattiRadicale; }
	inline void cleanup ( void );
	inline Glib::ustring get_xml_string ( const Glib::ustring &language ) const;	

private:
	Glib::ustring _kanji;
	list<Glib::ustring> *_onyomi;
	list<Glib::ustring> *_kunyomi;
	Glib::ustring _significato;
	Glib::ustring _radicale;
	unsigned char _tratti;
	unsigned char _trattiRadicale;

	void parse_letture ( const Glib::ustring &str, list<Glib::ustring> &listStr );
	void create_string ( const list<Glib::ustring> &listStr, Glib::ustring &str ) const;
	inline bool contiene_stringa ( const list<Glib::ustring> &listStr, const Glib::ustring &str ) const;
	
};

inline Kanji::
Kanji ( const Kanji &kan ) :
	_kanji ( kan._kanji ), _significato ( kan._significato ), _radicale ( kan._radicale ), _tratti ( kan._tratti ), _trattiRadicale ( kan._trattiRadicale )
{
	_contesto = kan._contesto;
	_valutazione = new char[ _numeroTest ];
	_dataEsame = new time_t[ _numeroTest ];
	char *pv = _valutazione;
	time_t *pt = _dataEsame;
	for ( unsigned short n = 0; n < _numeroTest; n++ )
	{
		*(pv + n) = *(kan._valutazione + n);
		*(pt + n) = *(kan._dataEsame + n);
	}
	_testSvolti = kan._testSvolti;
	_errata = kan._errata;
	_onyomi = new list<Glib::ustring> ( *(kan._onyomi) );
	_kunyomi = new list<Glib::ustring> ( *(kan._kunyomi) );
}

inline Kanji::
~Kanji()
{
	delete _onyomi;
	delete _kunyomi;
}

inline bool Kanji::
operator<( const Kanji &kan ) const
{
	return _kanji.raw () < kan._kanji.raw ();
}

inline bool Kanji::
operator==( const Kanji &kan ) const
{
	return _kanji.raw () == kan._kanji.raw ();
}

inline void Kanji::
set_kanji ( const char *cstr )
{
	if ( cstr )
		_kanji.assign ( cstr );
}

inline void Kanji::
set_onyomi ( const list<Glib::ustring> &setStr )
{
	_onyomi->clear ();
	_onyomi->insert ( _onyomi->begin(), setStr.begin (), setStr.end () );
}

inline void Kanji::
set_onyomi ( const Glib::ustring &str )
{
	_onyomi->clear ();
	parse_letture ( str, *_onyomi );
}

inline Glib::ustring Kanji::
get_onyomi ( void ) const
{
	Glib::ustring _str = "";
	create_string ( *_onyomi, _str );
	return _str;
}

inline void Kanji::
set_kunyomi ( const list<Glib::ustring> &setStr )
{
	_kunyomi->clear ();
	_kunyomi->insert ( _kunyomi->begin(), setStr.begin (), setStr.end () );
}

inline void Kanji::
set_kunyomi ( const Glib::ustring &str )
{
	_kunyomi->clear ();
	parse_letture ( str, *_kunyomi );
}

inline Glib::ustring Kanji::
get_kunyomi ( void ) const
{
	Glib::ustring _str = "";
	create_string ( *_kunyomi, _str );
	return _str;
}

inline void Kanji::
set_significato ( const char *cstr )
{
	if ( cstr )
		_significato.assign ( cstr );
}

inline void Kanji::
set_radicale ( const char *cstr )
{
	if ( cstr )
		_radicale.assign ( cstr );
}

inline bool Kanji::
contiene_stringa ( const list<Glib::ustring> &listStr, const Glib::ustring &str ) const
{
	if ( listStr.size() > 0 )
	{
		list<Glib::ustring>::const_iterator _iter = listStr.begin ();
		list<Glib::ustring>::const_iterator _end = listStr.end ();
		while ( _iter != _end )
		{
			if ( _iter->raw().find ( str.raw() ) != string::npos )
				return true;
			_iter++;
		}
	}
	return false;
}

inline void Kanji::
cleanup ( void )
{
	set_kanji ( "" );
	set_onyomi ( "" );
	set_kunyomi ( "" );
	set_significato ( "" );
	set_radicale ( "" );
	set_tratti ( static_cast<unsigned char>( 0 ) );
	set_tratti_radicale ( static_cast<unsigned char>( 0 ) );
	set_contesto ( "" );
	reset_stats ();
}

inline Glib::ustring Kanji::
get_xml_string ( const Glib::ustring &language ) const
{
	Glib::ustring str;
	str.append ( Glib::ustring ( "<kanji>\n" ) );
	str.append ( get_voce_xml () );
	str.append ( Glib::ustring ( "\t<signum>" + _kanji + "</signum>\n" ) );
	str.append ( Glib::ustring ( "\t<radix>" + _radicale + "</radix>\n" ) );
	str.append ( Glib::ustring ( "\t<onyomi>" + get_onyomi () + "</onyomi>\n" ) );
	str.append ( Glib::ustring ( "\t<kunyomi>" + get_kunyomi () + "</kunyomi>\n" ) );
	str.append ( Glib::ustring ( "\t<notio lang=\"" + language + "\">" + _significato + "</notio>\n" ) );
	str.append ( Glib::ustring ( "\t<signa>" + Glib::ustring::format ( static_cast<int>( _tratti ) ) + "</signa>\n" ) );
	str.append ( Glib::ustring ( "\t<radix_signa>" + Glib::ustring::format ( static_cast<int>( _trattiRadicale ) ) + "</radix_signa>\n" ) );
	str.append ( Glib::ustring ( "</kanji>\n" ) );
	return str;
}

#endif // _KANJI_H_
